Skip to main content

WebSocket Integration Guide

Overview

The FF Messaging Service provides real-time messaging capabilities through WebSocket connections using Socket.IO. This guide covers the WebSocket events, authentication, and message handling.

Connection Setup

Initialize Socket.IO Client

const socket = io("http://your-server:5000", {
transports: ["websocket"],
autoConnect: true
});

Connection Events

// Connection established
socket.on("connect", () => {
console.log("Connected to WebSocket server");
});

// Connection lost
socket.on("disconnect", () => {
console.log("Disconnected from WebSocket server");
});

Authentication

Register User

socket.emit("register_user", {
authid: "user-auth-id",
sessid: "session-id"
});

// Handle registration response
socket.on("register_success", (data) => {
console.log("Registration successful", data);
// data.offline_messages contains count of pending messages
});

socket.on("register_failure", (data) => {
console.error("Registration failed:", data.error);
});

Register Organization

socket.emit("register_organization", {
authid: "user-auth-id",
sessid: "session-id",
from_oid: 123 // Organization ID
});

Message Operations

Send Message

socket.emit("new_message", {
to: 456, // Recipient user ID
to_oid: 789, // Optional: Recipient organization ID
from_oid: 123, // Optional: Sender organization ID
message: "Hello!",
eid: 101, // Optional: Entity ID
attachment: { // Optional: Attachment
file_name: "doc.pdf",
file_url: "https://..."
}
});

Receive Messages

socket.on("new_message", (data) => {
console.log("New message received:", data);
// data contains: sender_id, message, timestamp, etc.

// Acknowledge receipt
socket.emit("delivery_receipt", {
message_id: data._id,
message_hash: data.hash
});

// Mark as read
socket.emit("read_receipt", {
message_id: data._id,
message_hash: data.hash
});
});

Typing Indicators

Send Typing Status

// User starts typing
socket.emit("typing_start", {
to: 456, // Recipient user ID
to_oid: 789, // Optional: Organization ID
eid: 101 // Optional: Entity ID
});

// User stops typing
socket.emit("typing_stop", {
to: 456,
to_oid: 789,
eid: 101
});

Receive Typing Status

socket.on("typing_status", (data) => {
const { from, is_typing } = data;
console.log(`User ${from} is ${is_typing ? 'typing...' : 'stopped typing'}`);
});

Presence Management

Check Online Status

socket.emit("check_online_status", {
user_id: 456, // Check user status
organization_id: 789 // Check organization status
});

socket.on("online_status", (data) => {
if (data.user_id) {
console.log(`User ${data.user_id} is ${data.online ? 'online' : 'offline'}`);
} else {
console.log(`Organization ${data.organization_id} is ${data.online ? 'online' : 'offline'}`);
}
});

Heartbeat

// Send heartbeat every 25 seconds
setInterval(() => {
socket.emit("heartbeat");
}, 25000);

socket.on("heartbeat_ack", (data) => {
console.log("Heartbeat acknowledged:", data.message);
});

Error Handling

socket.on("error", (data) => {
console.error("Socket error:", data.error);
});

Complete Example

const socket = io("http://your-server:5000");

// Connection management
socket.on("connect", () => {
console.log("Connected, socket ID:", socket.id);
registerUser();
});

socket.on("disconnect", () => {
console.log("Disconnected");
stopHeartbeat();
});

// User registration
function registerUser() {
socket.emit("register_user", {
authid: "user-auth-id",
sessid: "session-id"
});
}

// Message handling
socket.on("new_message", (data) => {
displayMessage(data);
socket.emit("delivery_receipt", {
message_id: data._id,
message_hash: data.hash
});
});

// Typing indicators
let typingTimeout;
function handleTyping(recipient_id) {
socket.emit("typing_start", { to: recipient_id });

clearTimeout(typingTimeout);
typingTimeout = setTimeout(() => {
socket.emit("typing_stop", { to: recipient_id });
}, 1000);
}

// Heartbeat
let heartbeatInterval;
function startHeartbeat() {
heartbeatInterval = setInterval(() => {
socket.emit("heartbeat");
}, 25000);
}

function stopHeartbeat() {
if (heartbeatInterval) {
clearInterval(heartbeatInterval);
}
}

Best Practices

  1. Connection Management

    • Implement reconnection logic
    • Handle disconnects gracefully
    • Maintain heartbeat
  2. Message Handling

    • Always acknowledge message receipt
    • Implement message queuing for offline scenarios
    • Handle errors appropriately
  3. Performance

    • Use WebSocket transport when possible
    • Implement throttling for typing indicators
    • Bundle messages when appropriate
  4. Security

    • Validate all incoming messages
    • Implement proper authentication
    • Handle sensitive data appropriately
  5. Error Handling

    • Implement proper error handling
    • Log errors appropriately
    • Provide user feedback when necessary